<?php
namespace Test;

use PDO;
use PDOException;
use Closure;
use Dybasedev\Dataman\Capsule\Manager as DB;

class Tester
{
    protected static $db;

    public static $store;

    public static function run()
    {
        $start = microtime(true);

        printf("Convert program is running...\n");

        $connection = array(
            'driver' => 'mysql',
            'host' => 'localhost',
            'database' => 'convert',
            'username' => 'root',
            'password' => 'xopns3847878',
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => '',
            'strict' => false,
        );

        printf("Set database configuration, and connect to [%s], please hold on...\n", $connection['host']);
        static::$db = new DB;

        static::$db->setFetchMode(PDO::FETCH_CLASS);

        static::$db->addConnection($connection);

        static::$db->setAsGlobal();

        // 清空数据库，并将自动递增值清零
        printf("Launch progress [Clear database's old data]:\n");
        foreach (DB::getTables() as $table) {
            printf("  * Clear table %-40s", '[' . $table . ']');
            DB::table($table)->truncate();
            printf("ok!\n");

            // DB::schema()->table($table, function($table) {
            //     $table->engine('innoDB');
            // });
        }

        printf("Launch progress [Convert Task]:\n");
        static::startConvert();

        // 转换为MyISAM格式
        foreach (DB::getTables() as $table) {
            printf("  * Change table engine %-40s", '[' . $table . ']');
            DB::schema()->table($table, function($table) {
                $table->engine('MyISAM');
            });
            printf("ok!\n");
        }

        // 打印结果
        printf("\n\nConvert progress is over. Processed %.5f second\n", microtime(true) - $start);
    }

    /**
     * 重写后的转换过程
     */
    public static function startConvert()
    {
        // 基本数据初始化
        // 
        printf("  Initializing base data\n");
        static::addDomain(static::$db->connection(), array('space' => 0, 'domain' => '根域', 'created_time' => time(), 'update_time' => 0));
        static::addDomain(static::$db->connection(), array('space' => 1, 'domain' => '全局域', 'created_time' => time(), 'update_time' => 0));

        static::addUser(static::$db->connection(), array('user' => 'super_admin', 'password' => md5('123456'), 'name' => 'SuperAdministrator', 'space' => 1, 'created_time' => time(), 'update_time' => 0));
        static::addUser(static::$db->connection(), array('user' => 'admin', 'password' => md5('123456'), 'name' => 'Administrator', 'space' => 2, 'created_time' => time(), 'update_time' => 0));

        printf("  Convert school data from old database\n");
        (new ConvertSchool(static::$db->connection()))->convert();

    }


    /**
     * 添加组
     *
     * 依赖：v2_sys_bind
     *
     * @param [type] $connection [description]
     * @param [type] $data       [description]
     */
    public static function addGroup($connection, $data)
    {
        unset($data['select']);

        $groupid = $connection->table('v2_sys_group')->insertGetId($data);

        $connection->table('v2_sys_bind')->insert(array('id' => $groupid, 'idtype' => 1, 'parent' => $data['space'], 'parenttype' => 2, 'primary' => 1));

        return $groupid;
    }

    /**
     * 添加域
     *
     * 依赖：v2_sys_bind | v2_sys_domain | v2_sys_isolation
     *
     * @param [type] $connection [description]
     * @param [type] $data       [description]
     */
    public static function addDomain($connection, $data)
    {
        $id = $connection->table('v2_sys_domain')->insertGetId($data);

        $connection->table('v2_sys_isolation')->insert(array('container' => $id, 'subcontainer' => $id));

        if ($data['space'] > 0) {
            $containers = $connection->table('v2_sys_isolation')->where('subcontainer', '=', $data['space'])->groupBy('container')->lists('container');

            foreach ($containers as $value) {
                $add[] = array(
                    'container' => $value,
                    'subcontainer' => $id
                );
            }

            $connection->table('v2_sys_isolation')->insert($add);

        }

        return $id;
    }

    /**
     * 添加用户
     *
     * 依赖：v2_sys_bind | v2_sys_group
     *
     * @param [type]       $connection [description]
     * @param [type]       $data       [description]
     * @param [type]       $append     [description]
     * @param Closure|null $callback [description]
     */
    public static function addUser($connection, $data, $append = null, Closure $callback = null)
    {
        $id = $connection->table('v2_sys_user')->insertGetId($data);

        if (!isset($append['setSpace']) || $append['setSpace'] === false) {
            $primary = isset($append['primary']) ? $append['primary'] : 1;

            $connection->table('v2_sys_bind')->insert(array('id' => $id, 'idtype' => 0, 'parent' => $data['space'], 'parenttype' => 2, 'primary' => $primary));
        }

        // 判断是否具有附加信息
        // 首先判断是否涉及到用户组的添加和修改
        if (isset($append['group'])) {
            foreach ($append['group'] as $group) {

                // 判断是否设置了组的ID，如果设置则不在数据库新增一个用户组，反之则创建
                if (isset($group['id'])) {

                    $primary = isset($group['select']) && $group['select'] ? 1 : 0;

                    $connection->table('v2_sys_bind')->insert(array('id' => $id, 'idtype' => 0, 'parent' => $group['id'], 'parenttype' => 1, 'primary' => $primary));

                } else {

                    $group['space'] = $data['space'];

                    // 调用用户组添加触发器
                    $groupid = static::addGroup($connection, $group);

                    // 判断是否作用户的用户组
                    if (isset($group['select'])) {
                        $connection->table('v2_sys_bind')->insert(array('id' => $id, 'idtype' => 0, 'parent' => $groupid, 'parenttype' => 1));
                    }

                    if (!is_null($callback)) {
                        $group['id'] = $groupid;
                        call_user_func($callback, $group);
                    }

                }


            }
        }

        return $id;
    }

//     public static function startConvert()
//     {   
//         /**
//         转换事件：事件会伴随转换过程而触发
//          */
//         $eventHanlder = function($event, $data) {
//             switch ($event) {
//                 case 'convert.start':
//                     printf("  School Convert: ID = %2s; status = %s;\n\n", $data['id'], $data['isEnable']);
//                     if (!$data['isEnable']) {
//                         printf("    * [WARINIG] Invalid data! IGNORE!\n\n");
//                         return false;
//                     }
//                     printf("    Convert initializing, start time [%s]\n\n", date("H:i:s"));
//                     break;
//                 case 'convert.transaction.start':

//                     break;
//                 case 'convert.result':

//             }
//         };


//         /**
//         原始数据初始化
//          */
//         static::addDomain(static::$db->connection(), array('space' => 0, 'domain' => '根域', 'created_time' => time(), 'update_time' => 0));
//         static::addDomain(static::$db->connection(), array('space' => 1, 'domain' => '全局域', 'created_time' => time(), 'update_time' => 0));


//         /**
//         转换过程
//          */
//         DB::convert()->simple(['yuanbao_v1', 't_kindergarten'], ['convert', 'v2_school'], function($converter) use ($trigger, $userAddTrigger) {

//             printf("\t\t* School information convert.\n");
//             $converter->from('name')->to('name');
//             $converter->from('createDate')->to('created_time', function($value) { return strtotime($value); });
//             $converter->from('modifyDate')->to('update_time', function($value) {
//                 if (empty($value)) {
//                     return 0;
//                 }
//                 return strtotime($value);
//             });

//             $converter->fill('telphone', '');
//             $converter->fill('address', '');
//             $converter->fill('sort', 0);
//             $converter->fill('status', 1);
//             $converter->fill('type', 0);


//             $converter->trigger(function($converter, $add, $row) {
//                 printf("\t* Register the school data build trigger.\n");
//                 $connection = $converter->getConnection();

//                 $spaceid = Tester::addDomain($connection, array('space' => 2, 'domain' => $add['name'], 'created_time' => time(), 'update_time' => 0));
//                 // $spaceid = $trigger($connection, array('space' => 2, 'domain' => $add['name'], 'created_time' => time(), 'update_time' => 0));

//                 $converter->fill('space', $spaceid);


//                 // 旧的校长（园长）账号数据读取
//                 $user = $connection->table('yuanbao_v1.t_user')->where('username', '=', $row['directorCode'])->first();

//                 // 旧的校长（园长）账号数据转换
//                 $data = array(
//                     'name' => $user['name'],
//                     'user' => $user['username'],
//                     'password' => $user['password'],
//                     'login_count' => $user['loginNum'] ?: 0,
//                     'created_time' => strtotime($user['createDate']),
//                     'update_time' => empty($user['modifyDate']) ? 0 : strtotime($user['modifyDate']),
//                     'nickname' => $user['nickName'] ?: '',
//                     'avatar' => $user['img'] ?: '',
//                     'telphone' => $user['mobile'] ?: '',
//                     'status' => $user['status'],
//                     'email' => $user['email'] ?: '',
//                     'space' => $spaceid
//                     );

//                 $append = array(
//                     'group' => array(
//                         array('space' => $spaceid, 'group' => '校长', 'created_time' => time(), 'select' => true),
//                         array('space' => $spaceid, 'group' => '老师', 'created_time' => time()),
//                         array('space' => $spaceid, 'group' => '家长', 'created_time' => time()),
//                         array('space' => $spaceid, 'group' => '医生', 'created_time' => time())
//                         )
//                     );

//                 // $userid = $userAddTrigger($connection, $data, $append);
//                 // 添加校长账号
//                 $groupinfo = [];
//                 $userid = Tester::addUser($connection, $data, $append, function($record) use (&$groupinfo) {
//                     printf("\t* Add user group (or role) into the school manager data.\n");
//                     $groupinfo[] = $record;
//                 });

//                 $converter->fill('master_id', $userid);

//                 // 现在开始写入学校内的班级
//                 // 在写入班级的同时，创建相关依赖数据
//                 // 包括班级教师、学生和家长
//                 // 班级的课表和荣誉榜
//                 Tester::schoolClassAdd($connection, $add['name'], $row['directorCode'], $spaceid, $groupinfo);

//                 // 现在开始写入学校内所有用户账号
//                 // Tester::schoolUserAdd($connection, $add['name'], $row['directorCode'], $spaceid, $groupinfo);

//             });
//         }, $eventHanlder);
//     }


//     *
//      * 校内所有账户写入
//      * 
//      * @param  [type] $connection       [description]
//      * @param  [type] $kindergartenName [description]
//      * @param  [type] $directorCode     [description]
//      * @param  [type] $spaceid          [description]
//      * @param  [type] $groupinfo        [description]
//      * @return [type]                   [description]

//     public static function schoolUserAdd($connection, $kindergartenName, $directorCode, $spaceid, $groupinfo)
//     {

//         $users = $connection->select("
// SELECT
//     t_user.*, t_kindergarten_user.kindergartenName AS kindergartenName,
//     t_user_role.roleCode AS role
// FROM
//     yuanbao_v1.t_user
// JOIN (
//     SELECT
//         *
//     FROM
//         yuanbao_v1.t_kindergarten_user
//     WHERE
//         kindergartenName = '$kindergartenName'
// ) as t_kindergarten_user ON t_kindergarten_user.username = t_user.username
// JOIN (
//     SELECT
//         *
//     FROM
//         yuanbao_v1.t_user_role
//     GROUP BY
//         username
// ) AS t_user_role ON t_user_role.username = t_user.username
// WHERE t_user.username != '$directorCode' AND t_user.status = 1 AND t_user.id > 0
// GROUP BY t_user.username;
// ");


//         $check = [
//             'ROLE_DIRECTOR' => '校长',
//             'ROLE_TEACHER' => '老师',
//             'ROLE_PARENT' => '家长',
//             'ROLE_DOCTOR' => '医生'
//             ];

//         foreach ($users as $user) {
//             printf("\t    + Add user from old database [%s]\n", $user['username']);

//             $data = array(
//                 'name' => $user['name'],
//                 'user' => $user['username'],
//                 'password' => $user['password'],
//                 'login_count' => $user['loginNum'] ?: 0,
//                 'created_time' => strtotime($user['createDate']),
//                 'update_time' => empty($user['modifyDate']) ? 0 : strtotime($user['modifyDate']),
//                 'nickname' => $user['nickName'] ?: '',
//                 'avatar' => $user['img'] ?: '',
//                 'telphone' => $user['mobile'] ?: '',
//                 'status' => $user['status'],
//                 'email' => $user['email'] ?: '',
//                 'space' => $spaceid
//                 );

//             $group = $check[$user['role']];

//             $data['user_type'] = in_array($user['role'], ['ROLE_DIRECTOR', 'ROLE_TEACHER', 'ROLE_DOCTOR']) ? 0 : 1; 

//             $append = [];

//             foreach ($groupinfo as $value) {
//                 if ($value['group'] == $group) {
//                     $value['select'] = true;
//                     $append[] = $value;
//                     break;
//                 }
//             }

//             Tester::addUser($connection, $data, $append);
//         }

//         // DB::convert()->simple(['yuanbao_v1', 't_kindergarten'], ['convert', 'v2_school'], function($converter) {

//         // });
//     }


}